#ifndef __TESTS_TEST1_COMPONENTS_TEST_IMPL_H__
#define __TESTS_TEST1_COMPONENTS_TEST_IMPL_H__

#include "../../include/ibase_impl.h"
#include "ifaces.h"

#include <list>

namespace Test
{

  class IMessageImpl
    : public CoClassBase
        <
          TL::TypeListAdapter
            <
              IMessage
            >
        >
  {
  public:
    BOSS_DECLARE_CLSID(7221662f-f6f4-4049-aa9b-8fa8e21686d9)

    IMessageImpl()
      : Data(0)
    {
    }

    // IMessage
    virtual void BOSS_CALL_TYPE Set(unsigned long data)
    {
      ISyncObject Lock(GetSynObj());
      Data = data;
    }
    virtual unsigned long BOSS_CALL_TYPE Get() const
    {
      ISyncObject Lock(GetSynObj());
      return Data;
    }

  private:
    unsigned long Data;
  };

  class IReceiverImpl
    : public CoClassBase
        <
          TL::TypeListAdapter
            <
              IReceiver
            >
        >
  {
  public:
    BOSS_DECLARE_CLSID(f3894f75-7a3a-4bbd-b7d4-f49dbdc6e9d2)

    // IReceiver
    virtual void BOSS_CALL_TYPE OnMsg(IMessage *msg)
    {
      if (!msg)
        return;
      ProcessMsg(msg);
    }

  protected:
    virtual void ProcessMsg(IMessage *msg) = 0;

  };

  class IMessageMgrImpl
    : public CoClassBase
        <
          TL::TypeListAdapter
            <
              IMessageMgr
            >
        >
  {
  public:
    BOSS_DECLARE_CLSID(6eada281-a118-4b27-b57c-ae14a89c4799)

    // IMessageMgr
    virtual TResult BOSS_CALL_TYPE Subscribe(IReceiver *receiver)
    {
      ISyncObject Lock(GetSynObj());
      Receivers.push_back(IReceiverPtr(receiver));
      return rcOk;
    }
    virtual TResult BOSS_CALL_TYPE Unsubscribe(IReceiver *receiver)
    {
      ISyncObject Lock(GetSynObj());
      for (IReceiverPool::iterator i = Receivers.begin() ; i != Receivers.end() ; ++i)
      {
        if (i->Get() == receiver)
        {
          Receivers.erase(i);
          return rcOk;
        }
      }
      return rcFail;
    }
    virtual TResult BOSS_CALL_TYPE SendMsg(IMessage *msg)
    {
      if (!msg)
        return rcBadParam;
      ISyncObject Lock(GetSynObj());
      for (IReceiverPool::iterator i = Receivers.begin() ; i != Receivers.end() ; ++i)
        (*i)->OnMsg(msg);
      return rcOk;
    }

  private:
    typedef RefObjPtr<IReceiver> IReceiverPtr;
    typedef std::list<IReceiverPtr> IReceiverPool;
    IReceiverPool Receivers;
  };

}

#endif  // !__TESTS_TEST1_COMPONENTS_TEST_IMPL_H__
